#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
标签管理器组件 - 用于管理和显示标签列表
"""

from PyQt5.QtWidgets import (
    QWidget, QVBoxLayout, QHBoxLayout, QLabel, QPushButton,
    QListWidget, QListWidgetItem, QMenu, QAction, QMessageBox,
    QColorDialog, QInputDialog
)
from PyQt5.QtCore import Qt, pyqtSignal
from PyQt5.QtGui import QColor, QIcon, QPixmap, QPainter

class ColorIcon:
    """颜色图标生成器"""
    
    @staticmethod
    def create(color, size=16):
        """创建颜色图标"""
        pixmap = QPixmap(size, size)
        pixmap.fill(Qt.transparent)
        
        painter = QPainter(pixmap)
        painter.setPen(Qt.black)
        painter.setBrush(color)
        painter.drawRect(0, 0, size-1, size-1)
        painter.end()
        
        return QIcon(pixmap)


class LabelManager(QWidget):
    """标签管理器组件"""
    
    # 自定义信号
    label_selected = pyqtSignal(str)  # 标签被选中
    label_added = pyqtSignal(str, QColor)  # 标签被添加
    label_removed = pyqtSignal(str)  # 标签被删除
    label_color_changed = pyqtSignal(str, QColor)  # 标签颜色被修改
    label_renamed = pyqtSignal(str, str)  # 标签被重命名(旧名称, 新名称)
    
    def __init__(self, parent=None):
        """初始化"""
        super().__init__(parent)
        
        # 标签数据（name -> {'color': QColor, 'count': int}）
        self.labels = {}
        
        # 设置界面
        self._setup_ui()
    
    def _setup_ui(self):
        """设置界面"""
        # 主布局
        main_layout = QVBoxLayout(self)
        
        # 标题标签
        title_label = QLabel("标签管理")
        title_label.setAlignment(Qt.AlignCenter)
        main_layout.addWidget(title_label)
        
        # 标签列表
        self.label_list = QListWidget()
        self.label_list.setContextMenuPolicy(Qt.CustomContextMenu)
        self.label_list.customContextMenuRequested.connect(self._show_context_menu)
        self.label_list.itemSelectionChanged.connect(self._on_selection_changed)
        main_layout.addWidget(self.label_list)
        
        # 按钮布局
        button_layout = QHBoxLayout()
        
        # 添加标签按钮
        self.add_button = QPushButton("添加标签")
        self.add_button.clicked.connect(self._on_add_clicked)
        button_layout.addWidget(self.add_button)
        
        # 删除标签按钮
        self.remove_button = QPushButton("删除标签")
        self.remove_button.clicked.connect(self._on_remove_clicked)
        self.remove_button.setEnabled(False)  # 默认禁用
        button_layout.addWidget(self.remove_button)
        
        main_layout.addLayout(button_layout)
        
        # 统计标签
        self.stats_label = QLabel("共0个标签")
        self.stats_label.setAlignment(Qt.AlignCenter)
        main_layout.addWidget(self.stats_label)
    
    def set_labels(self, labels):
        """
        设置标签列表
        
        Args:
            labels (list): 标签列表
        """
        # 清除当前标签
        self.labels = {}
        self.label_list.clear()
        
        # 添加标签
        for label in labels:
            if isinstance(label, dict):
                name = label.get("name", "")
                color = label.get("color", "#FF0000")
                count = label.get("count", 0)
                
                if name:
                    if isinstance(color, str):
                        color = QColor(color)
                    self.add_label(name, color, count)
            elif isinstance(label, str):
                self.add_label(label, QColor(Qt.red), 0)
        
        # 更新统计
        self._update_stats()
    
    def add_label(self, name, color=QColor(Qt.red), count=0):
        """
        添加标签
        
        Args:
            name (str): 标签名称
            color (QColor, optional): 标签颜色
            count (int, optional): 标签数量
            
        Returns:
            bool: 是否添加成功
        """
        # 检查标签是否已存在
        if name in self.labels:
            return False
        
        # 添加到数据结构
        self.labels[name] = {
            'color': color,
            'count': count
        }
        
        # 创建列表项
        item = QListWidgetItem()
        item.setText(f"{name} ({count})")
        item.setIcon(ColorIcon.create(color))
        item.setData(Qt.UserRole, name)
        
        # 添加到列表
        self.label_list.addItem(item)
        
        # 更新统计
        self._update_stats()
        
        # 发射信号
        self.label_added.emit(name, color)
        
        return True
    
    def remove_label(self, name):
        """
        删除标签
        
        Args:
            name (str): 标签名称
            
        Returns:
            bool: 是否删除成功
        """
        # 检查标签是否存在
        if name not in self.labels:
            return False
        
        # 查找列表项
        for i in range(self.label_list.count()):
            item = self.label_list.item(i)
            if item.data(Qt.UserRole) == name:
                # 从列表中移除
                self.label_list.takeItem(i)
                break
        
        # 从数据结构中移除
        del self.labels[name]
        
        # 更新统计
        self._update_stats()
        
        # 发射信号
        self.label_removed.emit(name)
        
        return True
    
    def update_label_count(self, name, count):
        """
        更新标签数量
        
        Args:
            name (str): 标签名称
            count (int): 新的数量
            
        Returns:
            bool: 是否更新成功
        """
        # 检查标签是否存在
        if name not in self.labels:
            return False
        
        # 更新数据结构
        self.labels[name]['count'] = count
        
        # 更新列表项
        for i in range(self.label_list.count()):
            item = self.label_list.item(i)
            if item.data(Qt.UserRole) == name:
                item.setText(f"{name} ({count})")
                break
        
        return True
    
    def get_label_color(self, name):
        """
        获取标签颜色
        
        Args:
            name (str): 标签名称
            
        Returns:
            QColor: 标签颜色，如果标签不存在则返回None
        """
        if name in self.labels:
            return self.labels[name]['color']
        return None
    
    def get_selected_label(self):
        """
        获取当前选中的标签
        
        Returns:
            str: 标签名称，如果没有选中则返回None
        """
        items = self.label_list.selectedItems()
        if items:
            return items[0].data(Qt.UserRole)
        return None
    
    def _update_stats(self):
        """更新统计信息"""
        total_labels = len(self.labels)
        total_annotations = sum(label['count'] for label in self.labels.values())
        
        self.stats_label.setText(f"共{total_labels}个标签，{total_annotations}个标注")
    
    def _on_selection_changed(self):
        """选择改变事件"""
        # 获取当前选中的标签
        label = self.get_selected_label()
        
        # 更新删除按钮状态
        self.remove_button.setEnabled(label is not None)
        
        # 发射信号
        if label:
            self.label_selected.emit(label)
    
    def _on_add_clicked(self):
        """添加按钮点击事件"""
        # 这个事件需要在主窗口中处理
        # 因为需要显示添加标签对话框
        pass
    
    def _on_remove_clicked(self):
        """删除按钮点击事件"""
        # 获取当前选中的标签
        label = self.get_selected_label()
        if not label:
            return
        
        # 确认对话框
        reply = QMessageBox.question(
            self,
            "删除标签",
            f"确定要删除标签 \"{label}\" 吗？",
            QMessageBox.Yes | QMessageBox.No,
            QMessageBox.No
        )
        
        if reply == QMessageBox.Yes:
            self.remove_label(label)
    
    def _show_context_menu(self, pos):
        """显示右键菜单"""
        # 获取当前选中的标签
        item = self.label_list.itemAt(pos)
        if not item:
            return
        
        label = item.data(Qt.UserRole)
        
        # 创建菜单
        menu = QMenu(self)
        
        # 添加菜单项
        change_color_action = QAction("修改颜色", self)
        rename_action = QAction("重命名", self)
        delete_action = QAction("删除", self)
        
        menu.addAction(change_color_action)
        menu.addAction(rename_action)
        menu.addSeparator()
        menu.addAction(delete_action)
        
        # 连接信号
        change_color_action.triggered.connect(lambda: self._on_change_color(label))
        rename_action.triggered.connect(lambda: self._on_rename(label))
        delete_action.triggered.connect(lambda: self._on_delete(label))
        
        # 显示菜单
        menu.exec_(self.label_list.mapToGlobal(pos))
    
    def _on_change_color(self, label):
        """修改颜色事件"""
        # 获取当前颜色
        color = self.get_label_color(label)
        
        # 打开颜色对话框
        new_color = QColorDialog.getColor(color, self, "选择标签颜色")
        if not new_color.isValid():
            return
        
        # 更新颜色
        self.labels[label]['color'] = new_color
        
        # 更新列表项
        for i in range(self.label_list.count()):
            item = self.label_list.item(i)
            if item.data(Qt.UserRole) == label:
                item.setIcon(ColorIcon.create(new_color))
                break
        
        # 发射信号
        self.label_color_changed.emit(label, new_color)
    
    def _on_rename(self, label):
        """重命名事件"""
        # 显示输入对话框
        new_name, ok = QInputDialog.getText(
            self,
            "重命名标签",
            f"请输入新的标签名称（当前：{label}）：",
            text=label
        )
        
        if ok and new_name:
            # 检查新名称是否已存在
            if new_name in self.labels and new_name != label:
                QMessageBox.warning(self, "重命名失败", f"标签名称 \"{new_name}\" 已存在")
                return
            
            if new_name == label:
                return  # 名称没有变化
            
            # 更新内部数据结构
            if label in self.labels:
                label_data = self.labels[label]
                del self.labels[label]
                self.labels[new_name] = label_data
                
                # 更新列表项
                for i in range(self.label_list.count()):
                    item = self.label_list.item(i)
                    if item.data(Qt.UserRole) == label:
                        item.setText(f"{new_name} ({label_data['count']})")
                        item.setData(Qt.UserRole, new_name)
                        break
                
                # 发射信号
                self.label_renamed.emit(label, new_name)
    
    def _on_delete(self, label):
        """删除事件"""
        # 确认对话框
        reply = QMessageBox.question(
            self, 
            "确认删除", 
            f"确定要删除标签 \"{label}\" 吗？",
            QMessageBox.Yes | QMessageBox.No,
            QMessageBox.No
        )
        
        if reply == QMessageBox.Yes:
            self.remove_label(label) 